package cn.script.app.start;

import cn.script.app.bean.AppInfo;
import cn.script.app.bean.RoleInfo;
import cn.script.app.bean.RunInfo;
import cn.script.app.bean.ScriptInfo;
import cn.script.game.dup.*;
import cn.script.game.prof.Pi;
import cn.script.game.prof.PiDefine;
import cn.script.util.Delay;
import cn.script.util.LogOut;
import cn.script.util.StringUtils;

import java.util.concurrent.*;

public class GameStart {

    private static GameStart gs = new GameStart();

    private AppInfo appInfo;

    private Future<Object> futureRate;

    private ThreadPoolExecutor poolExecutor;

    private AbstractDup nowDup;

    private boolean status = false;

    private Pi nowPi;

    private LinkedBlockingQueue<Callable<Object>> callables = new LinkedBlockingQueue<>(1);

    public GameStart() {
        this.poolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
    }

    public static boolean start(AppInfo appInfo) {
        if (gs.isStatus()) {
            return true;
        }
        gs.appInfo = appInfo;
        return gs.start();
    }

    public static boolean stop() {
        if (!gs.isStatus()) {
            return true;
        }
        return gs.stop_();
    }

    public boolean check() {
        RoleInfo roleInfo = this.appInfo.getmInfo();
        if (StringUtils.toLong(roleInfo.getHwnd()) == null) {
            LogOut.out("请选择主游戏窗口");
            return false;
        }
        String dup = this.appInfo.getsInfo().getDup();
        if (StringUtils.isBank(dup)) {
            LogOut.out("请选择副本");
            return false;
        }
        if (dup.equals("魔族要塞") || dup.equals("众神副本")
                || dup.equals("冰宫") || dup.equals("蛮岩") || dup.equals("弑神")) {
            return true;
        }
        RoleInfo tRoleInfo = this.appInfo.gettInfo();
        if (StringUtils.isBank(tRoleInfo.getName())) {
            LogOut.out("请输入队友名称");
            return false;
        }
        if (StringUtils.toLong(tRoleInfo.getHwnd()) == null) {
            LogOut.out("请获取组队窗口");
            return false;
        }
        return true;
    }
    private void initPro(){
        ScriptInfo scriptInfo = this.appInfo.getsInfo();
        String professional = scriptInfo.getProfessional();
        if (professional.equals("星辰")){
            nowPi = PiDefine.xc();
        }
        if (professional.equals("冰法")){
            nowPi = PiDefine.hf();
        }
        if (professional.equals("火法")){
            nowPi = PiDefine.hf();
        }
    }

    public boolean init() {
        initPro();
        String dupName = this.appInfo.getsInfo().getDup();
        try {
            this.appInfo.getmInfo().init();

            boolean off = this.appInfo.gettInfo().getOff();
            String d_name = this.appInfo.gettInfo().getName();
            if (off) {
                d_name = "仙中之王|" + dupName;
            }
            if (!dupName.equals("魔族要塞") && !dupName.equals("众神副本")
                    && !dupName.equals("冰宫") && !dupName.equals("蛮岩")
                    && !dupName.equals("弑神")) {
                this.appInfo.gettInfo().init();
            }
            if ( dupName.equals("弑神")){
                this.nowDup = new SisDup(nowPi, this.appInfo.getmInfo().getGo(), this.appInfo.getsInfo().getBoss());
            }
            if ( dupName.equals("众神副本")){
                this.nowDup = new ZsDup(nowPi, this.appInfo.getmInfo().getGo());
            }
            if ( dupName.equals("冰宫")){
                this.nowDup = new BgDup(nowPi, this.appInfo.getmInfo().getGo());
            }

            if ( dupName.equals("蛮岩")){
                this.nowDup = new MyDup(nowPi, this.appInfo.getmInfo().getGo());
            }

            if (dupName.equals("魔族要塞")) {
                this.nowDup = new YsDup(nowPi, this.appInfo.getmInfo().getGo(), this.appInfo.getsInfo().getBoss());
            }
            if (dupName.equals("生死劫最后的救赎")) {
                this.nowDup = new SsDup(nowPi, this.appInfo.getmInfo().getGo(),
                        this.appInfo.gettInfo().getGo(), this.appInfo.getsInfo().getTermCity(), d_name
                        , this.appInfo.getsInfo().getBoss());
            }
            if (dupName.equals("神秘的天堂")) {
                this.nowDup = new TtDup(nowPi, this.appInfo.getmInfo().getGo(),
                        this.appInfo.gettInfo().getGo(), this.appInfo.getsInfo().getTermCity(), d_name);
            }

            this.nowDup.init();
        } catch (Exception e) {
            e.printStackTrace();
            LogOut.out("绑定游戏窗口失败");
            return false;
        }
        return true;
    }

    public boolean checkNum() {
        Integer num = StringUtils.toInt(this.appInfo.getsInfo().getNum());
        if (num == null || num <= 0) {
            return true;
        }
        String oldNum = this.appInfo.getRunInfo().getOldNum();
        if (StringUtils.toInt(oldNum) == num) {
            LogOut.out("脚本执行完毕");
            return false;
        }
        return true;
    }

    public boolean start() {
        if (this.status) {
            return true;
        }
        if (!this.check()) {
            return false;
        }
        if (!this.init()) {
            return false;
        }
        this.status = true;
        Thread thread = new Thread(() -> {
            this.callables.clear();
            while (this.status) {
                if (!this.checkNum()) {
                    return;
                }
                if (this.callables.size() == 1) {
                    Delay.delay(100);
                    continue;
                }
                try {
                    this.callables.add(new Callable<Object>() {
                        @Override
                        public Object call() {
                            long startTime = System.currentTimeMillis();
                            GameStart.this.nowDup.launch();
                            GameStart.gs.addTime(System.currentTimeMillis() - startTime);
//                            LogOut.out("第%d次副本耗时:%d", ExecuteDup.this.num, time);
                            return 1;
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();

                }

            }
            System.out.println("执行任务结束");
        });
        thread.setName("任务线程");
        thread.start();


        Thread thread1 = new Thread(() -> {
            while (this.status) {
                try {
                    this.futureRate = this.poolExecutor.submit(this.callables.take());
                    this.futureRate.get();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println("执行线程结束");
        });
        thread1.setName("执行线程");
        thread1.start();
        return true;
    }

    public void addTime(long time) {
        RunInfo runInfo = this.appInfo.getRunInfo();
        runInfo.setNowTime(time + "");
        long totalTime = StringUtils.toLong(runInfo.getTotalTime()) + time;
        runInfo.setTotalTime(totalTime + "");
        int oldNum = StringUtils.toInt(runInfo.getOldNum()) + 1;
        runInfo.setOldNum(oldNum + "");
        runInfo.setAvgTime(totalTime / oldNum + "");
    }

    public boolean stop_() {
        if (!this.status) {
            return true;
        }
        this.status = false;
        boolean cancel = this.futureRate.cancel(true);
        if (!cancel) {
            LogOut.out("停止当前副本失败");
            this.status = true;
            return false;
        }
        RoleInfo roleInfo = this.appInfo.getmInfo();
        roleInfo.getGo().wio().unWindow();
        if (this.appInfo.gettInfo().getGo() != null) {
            this.appInfo.gettInfo().getGo().wio().unWindow();
        }
        return true;
    }

    public boolean isStatus() {
        return this.status;
    }
}
